home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.5 Applications 2002 November / SGI IRIX 6.5 Applications 2002 November.iso / dist / extras / netscape_lite.idb / usr / share / src / ns_plugin / npshell.c.z / npshell.c
Encoding:
C/C++ Source or Header  |  2001-12-20  |  13.1 KB  |  571 lines

  1. /*
  2.  * npshell.c
  3.  *
  4.  * Netscape Client Plugin API
  5.  * - Function that need to be implemented by plugin developers
  6.  *
  7.  * This file defines a "shell" plugin that plugin developers can use
  8.  * as the basis for a real plugin.  This shell just provides empty
  9.  * implementations of all functions that the plugin can implement
  10.  * that will be called by Netscape (the NPP_xxx methods defined in 
  11.  * npapi.h). 
  12.  *
  13.  * dp Suresh <dp@netscape.com>
  14.  *
  15.  *----------------------------------------------------------------------
  16.  * PLUGIN DEVELOPERS:
  17.  *    Implement your plugins here.
  18.  *    A sample text plugin is implemented here.
  19.  *    All the sample plugin does is displays any file with a
  20.  *    ".txt" extension in a scrolled text window. It uses Motif.
  21.  *----------------------------------------------------------------------
  22.  */
  23.  
  24. #define XP_UNIX
  25.  
  26. #include <Xm/Xm.h>
  27. #include "npapi.h"
  28.  
  29.  
  30. /*
  31.  * Replace this string with the MIME type and extension fields 
  32.  * for which your plugin should be registered.
  33.  */
  34.  
  35. /*--- Start custom code */
  36.  
  37. #define MIME_EXT_DESCRIPTION "text/x-movingtext:.mvtxt"
  38.  
  39. /*--- End custom code */
  40.  
  41. /****************************************************
  42.  * Instance state information about the plugin.
  43.  *
  44.  * PLUGIN DEVELOPERS:
  45.  *    Use this struct to hold per-instance information that you'll
  46.  *    need in the various functions in this file.
  47.  ***********************************************************************/
  48.  
  49. #define LEFT  0
  50. #define RIGHT 1
  51. #define UP    2
  52. #define DOWN  3
  53.  
  54. typedef struct _PluginInstance
  55. {
  56.     Widget    netscape_widget; /* The widget provided by netscape */
  57.     Display    *display;         /* Netscape's display connection */
  58.     uint16    mode;            /* NP_EMBED, NP_FULL, or NP_BACKGROUND */
  59.     uint32 width, height;
  60. /*--- Start custom code */
  61.  
  62.     char *string;
  63.     int direction; /* LEFT = 0, RIGHT = 1, UP = 2, DOWN = 3 */
  64.     int len;
  65.     GC gc;
  66.     int x, y,  bannerWidth, bannerHeight, ascent, descent;
  67.     XFontStruct *font;
  68.     XtIntervalId timerId;
  69.     XtAppContext appContext;
  70.     char *fontName;
  71.  
  72. /*--- End custom code */
  73.     
  74. } PluginInstance;
  75.  
  76.  
  77. static void DoAnimation(XtPointer clientData, XtIntervalId *id );
  78.  
  79. /***********************************************************************
  80.  *
  81.  * Empty implementations of plugin API functions
  82.  *
  83.  * PLUGIN DEVELOPERS:
  84.  *    You will need to implement these functions as required by your
  85.  *    plugin.
  86.  *
  87.  ***********************************************************************/
  88.  
  89. char *
  90. NPP_GetMIMEDescription(void)
  91. {
  92.     return( MIME_EXT_DESCRIPTION );
  93. }
  94.  
  95. NPError
  96. NPP_Initialize(void)
  97. {
  98.     return NPERR_NO_ERROR;
  99. }
  100.  
  101. void
  102. NPP_Shutdown(void)
  103. {
  104. }
  105.  
  106.  
  107. NPError 
  108. NPP_New(NPMIMEType pluginType,
  109.     NPP instance,
  110.     uint16 mode,
  111.     int16 argc,
  112.     char* argn[],
  113.     char* argv[],
  114.     NPSavedData* saved)
  115. {
  116.         PluginInstance* This;
  117.  
  118.     if (instance == NULL)
  119.         return NPERR_INVALID_INSTANCE_ERROR;
  120.         
  121.     instance->pdata = NPN_MemAlloc(sizeof(PluginInstance));
  122.     
  123.     This = (PluginInstance*) instance->pdata;
  124.  
  125.     if (This != NULL)
  126.     {
  127.                int i;
  128.         This->netscape_widget = NULL;
  129.         This->display = NULL;
  130.         This->mode = mode;    /* mode is NP_EMBED, NP_FULL, or NP_BACKGROUND (see npapi.h) */
  131.         This->width = 0;
  132.         This->height = 0;
  133.  
  134.         /* *Developers*: Initialize fields of your plugin
  135.          * instance data here.  If the NPSavedData is non-
  136.          * NULL, you can use that data (returned by you from
  137.          * NPP_Destroy to set up the new plugin instance.
  138.          */
  139.  
  140.         /*--- Start custom code */
  141.  
  142.         This->string = NULL;
  143.         This->direction = 0; 
  144.         This->len = 0;
  145.         This->timerId = 0;
  146.         This->x = 0; 
  147.         This->y = 0;
  148.         This->bannerWidth = 0;
  149.  
  150.         This->fontName = "fixed";
  151.  
  152.         /* get any args we recognize from the html file */
  153.  
  154.         for(i = 0; i < argc; i++)
  155.         {
  156.             if(!strcmp(argn[i], "FONT"))
  157.             This->fontName = XtNewString(argv[i]);
  158.  
  159.             if(!strcmp(argn[i], "DIRECTION"))
  160.             {
  161.             if(!strcmp(argv[i], "LEFT"))
  162.                 This->direction = LEFT;
  163.             if(!strcmp(argv[i], "RIGHT"))
  164.                 This->direction = RIGHT;
  165.             if(!strcmp(argv[i], "UP"))
  166.                 This->direction = UP;
  167.             if(!strcmp(argv[i], "DOWN"))
  168.                 This->direction = DOWN;
  169.             }
  170.         }
  171.  
  172.         /*--- End custom code */
  173.         
  174.         return NPERR_NO_ERROR;
  175.     }
  176.     else
  177.         return NPERR_OUT_OF_MEMORY_ERROR;
  178. }
  179.  
  180.  
  181. NPError 
  182. NPP_Destroy(NPP instance, NPSavedData** save)
  183. {
  184.     PluginInstance* This;
  185.  
  186.     if (instance == NULL)
  187.         return NPERR_INVALID_INSTANCE_ERROR;
  188.  
  189.     This = (PluginInstance*) instance->pdata;
  190.  
  191.     /* PLUGIN DEVELOPERS:
  192.      *    If desired, call NP_MemAlloc to create a
  193.      *    NPSavedDate structure containing any state information
  194.      *    that you want restored if this plugin instance is later
  195.      *    recreated.
  196.      */
  197.  
  198.     if (This != NULL) {
  199.         NPN_MemFree(instance->pdata);
  200.         instance->pdata = NULL;
  201.  
  202.         /*--- Start custom code */
  203.  
  204.         /* Stream is closed, we have the data, so start a timer to
  205.          * call the draw routine
  206.          */
  207.  
  208.         if(This->timerId)
  209.             XtRemoveTimeOut(This->timerId);
  210.         This->timerId = 0;
  211.  
  212.         /*--- End custom code */
  213.     }
  214.  
  215.     return NPERR_NO_ERROR;
  216. }
  217.  
  218.  
  219.  
  220. NPError 
  221. NPP_SetWindow(NPP instance, NPWindow* window)
  222. {
  223.     PluginInstance* This;
  224.  
  225.     Pixel bg, fg;
  226.     int num_fonts;
  227.  
  228.     if (instance == NULL)
  229.         return NPERR_INVALID_INSTANCE_ERROR;
  230.  
  231.     This = (PluginInstance*) instance->pdata;
  232.  
  233.     /*
  234.      * PLUGIN DEVELOPERS:
  235.      *    Before setting window to point to the
  236.      *    new window, you may wish to compare the new window
  237.      *    info to the previous window (if any) to note window
  238.      *    size changes, etc.
  239.      */
  240.  
  241.     This->display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
  242.     This->netscape_widget = XtWindowToWidget(This->display, (Window)window->window);
  243.     This->width = window->width;
  244.     This->height = window->height;
  245.  
  246.     /*--- Start custom code */
  247.  
  248.     /* We need lots of info to draw a string */
  249.  
  250.     This->appContext = XtWidgetToApplicationContext(This->netscape_widget);
  251.  
  252.     This->gc = XCreateGC(This->display,
  253.                  (Window)window->window, 0,
  254.                  (XGCValues *) NULL);
  255.  
  256.     XtVaGetValues(This->netscape_widget,
  257.               XmNbackground, &bg,
  258.               XmNforeground, &fg,
  259.               NULL);
  260.  
  261.     /* 
  262.      * Cheat - set the netscape window's border to 0 so we don't see the
  263.      * black outlines 
  264.      */
  265.  
  266.     XtVaSetValues(This->netscape_widget,
  267.               XmNborderWidth, 0,
  268.               NULL);
  269.  
  270.     XSetForeground(This->display, This->gc, fg);
  271.     XSetBackground(This->display, This->gc, bg);
  272.  
  273.     XListFonts(This->display, This->fontName, 1, &num_fonts); 
  274.  
  275.  
  276.     if (num_fonts)
  277.     {
  278.         This->font = XLoadQueryFont(This->display, This->fontName);    
  279.         XSetFont(This->display, This->gc, This->font->fid);
  280.     }
  281.  
  282.     /*--- End custom code */
  283.  
  284.     return NPERR_NO_ERROR;
  285. }
  286.  
  287.  
  288. NPError 
  289. NPP_NewStream(NPP instance,
  290.           NPMIMEType type,
  291.           NPStream *stream, 
  292.           NPBool seekable,
  293.           uint16 *stype)
  294. {
  295.     PluginInstance* This;
  296.  
  297.     if (instance == NULL)
  298.         return NPERR_INVALID_INSTANCE_ERROR;
  299.  
  300.     This = (PluginInstance*) instance->pdata;
  301.  
  302. /*--- Start custom code */
  303.  
  304.     /* We want a stream of data */
  305.  
  306.     *stype = NP_NORMAL;
  307.  
  308. /*--- End custom code */
  309.  
  310.     return NPERR_NO_ERROR;
  311. }
  312.  
  313.  
  314. /* PLUGIN DEVELOPERS:
  315.  *    These next 2 functions are directly relevant in a plug-in which
  316.  *    handles the data in a streaming manner. If you want zero bytes
  317.  *    because no buffer space is YET available, return 0. As long as
  318.  *    the stream has not been written to the plugin, Navigator will
  319.  *    continue trying to send bytes.  If the plugin doesn't want them,
  320.  *    just return some large number from NPP_WriteReady(), and
  321.  *    ignore them in NPP_Write().  For a NP_ASFILE stream, they are
  322.  *    still called but can safely be ignored using this strategy.
  323.  */
  324.  
  325. int32 STREAMBUFSIZE = 0X0FFFFFFF; /* If we are reading from a file in NPAsFile
  326.                    * mode so we can take any size stream in our
  327.                    * write call (since we ignore it) */
  328.  
  329. int32 
  330. NPP_WriteReady(NPP instance, NPStream *stream)
  331. {
  332.     PluginInstance* This;
  333.     if (instance != NULL)
  334.         This = (PluginInstance*) instance->pdata;
  335.  
  336.     /* Number of bytes ready to accept in NPP_Write() */
  337.     return STREAMBUFSIZE;
  338. }
  339.  
  340.  
  341. int32 
  342. NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)
  343. {
  344.     if (instance != NULL)
  345.     {
  346.         PluginInstance* This = (PluginInstance*) instance->pdata;
  347.  
  348.  
  349. /*--- Start custom code */
  350.  
  351.         /* Just get the data. If there is a lot, we'll get it in
  352.          * pieces, so be prepared to append
  353.          */
  354.  
  355.         This->string = XtRealloc(This->string, This->len + len + 2);
  356.  
  357.         strncpy(&(This->string[This->len]), buffer, len);
  358.  
  359.         This->len += len;
  360.  
  361.         This->string[This->len] = '\0';
  362.  
  363. /*--- End custom code */
  364.  
  365.     }
  366.  
  367.     return len;        /* The number of bytes accepted */
  368. }
  369.  
  370.  
  371. NPError 
  372. NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason)
  373. {
  374.     PluginInstance* This;
  375.     XCharStruct bounds;
  376.     int direction, ascent, descent;
  377.  
  378.     if (instance == NULL)
  379.         return NPERR_INVALID_INSTANCE_ERROR;
  380.     This = (PluginInstance*) instance->pdata;
  381.  
  382. /*--- Start custom code */
  383.  
  384.     /* OK, ready to go, find out how big the string is,
  385.      * and initialize the string's position
  386.      */
  387.  
  388.     XTextExtents(This->font, This->string, This->len,
  389.              &direction, &ascent, &descent, &bounds);
  390.  
  391.     This->bannerWidth = bounds.width;
  392.     This->bannerHeight = bounds.ascent + bounds.descent;
  393.     This->ascent = bounds.ascent;
  394.     This->descent = bounds.descent;
  395.  
  396.     if(This->direction == LEFT)
  397.     {
  398.         This->x = This->width;
  399.         This->y = This->bannerHeight;
  400.     }
  401.     else if(This->direction == RIGHT)
  402.     {
  403.         This->x = -This->bannerWidth;
  404.         This->y = This->bannerHeight;
  405.     }
  406.     else if(This->direction == DOWN)
  407.     {
  408.         This->x = 0;
  409.         This->y = 0;
  410.     }
  411.     else if(This->direction == UP)
  412.     {
  413.         This->x = 0;
  414.         This->y = This->bannerHeight + This->height;
  415.     }
  416.  
  417.     This->timerId = XtAppAddTimeOut(This->appContext,
  418.                     100,
  419.                     DoAnimation,
  420.                     (XtPointer)instance); 
  421.  
  422. /*--- End custom code */
  423.  
  424.     return NPERR_NO_ERROR;
  425. }
  426.  
  427.  
  428. void 
  429. NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname)
  430. {
  431.     PluginInstance* This;
  432.     if (instance != NULL)
  433.         This = (PluginInstance*) instance->pdata;
  434. }
  435.  
  436.  
  437. void 
  438. NPP_Print(NPP instance, NPPrint* printInfo)
  439. {
  440.     if(printInfo == NULL)
  441.         return;
  442.  
  443.     if (instance != NULL) {
  444.         PluginInstance* This = (PluginInstance*) instance->pdata;
  445.     
  446.         if (printInfo->mode == NP_FULL) {
  447.             /*
  448.              * PLUGIN DEVELOPERS:
  449.              *    If your plugin would like to take over
  450.              *    printing completely when it is in full-screen mode,
  451.              *    set printInfo->pluginPrinted to TRUE and print your
  452.              *    plugin as you see fit.  If your plugin wants Netscape
  453.              *    to handle printing in this case, set
  454.              *    printInfo->pluginPrinted to FALSE (the default) and
  455.              *    do nothing.  If you do want to handle printing
  456.              *    yourself, printOne is true if the print button
  457.              *    (as opposed to the print menu) was clicked.
  458.              *    On the Macintosh, platformPrint is a THPrint; on
  459.              *    Windows, platformPrint is a structure
  460.              *    (defined in npapi.h) containing the printer name, port,
  461.              *    etc.
  462.              */
  463.  
  464.             void* platformPrint =
  465.                 printInfo->print.fullPrint.platformPrint;
  466.             NPBool printOne =
  467.                 printInfo->print.fullPrint.printOne;
  468.             
  469.             /* Do the default*/
  470.             printInfo->print.fullPrint.pluginPrinted = FALSE;
  471.         }
  472.         else {    /* If not fullscreen, we must be embedded */
  473.             /*
  474.              * PLUGIN DEVELOPERS:
  475.              *    If your plugin is embedded, or is full-screen
  476.              *    but you returned false in pluginPrinted above, NPP_Print
  477.              *    will be called with mode == NP_EMBED.  The NPWindow
  478.              *    in the printInfo gives the location and dimensions of
  479.              *    the embedded plugin on the printed page.  On the
  480.              *    Macintosh, platformPrint is the printer port; on
  481.              *    Windows, platformPrint is the handle to the printing
  482.              *    device context.
  483.              */
  484.  
  485.             NPWindow* printWindow =
  486.                 &(printInfo->print.embedPrint.window);
  487.             void* platformPrint =
  488.                 printInfo->print.embedPrint.platformPrint;
  489.         }
  490.     }
  491. }
  492.  
  493. /*--- Start custom code */
  494.  
  495. static void DoAnimation(XtPointer clientData, XtIntervalId *id ) 
  496. {
  497.     NPP instance = (NPP)clientData;
  498.     PluginInstance* This = (PluginInstance*) instance->pdata;
  499.  
  500.     /* Draw the string */
  501.  
  502.     XDrawImageString(This->display, XtWindow(This->netscape_widget),
  503.         This->gc, This->x,
  504.         This->y,
  505.         This->string, This->len);
  506.  
  507.     /* Clear any space left to the sides */
  508.  
  509.     if(This->x > 0)
  510.     XClearArea(This->display, XtWindow(This->netscape_widget),
  511.            0, 0,
  512.            This->x,
  513.            This->height, FALSE);
  514.     
  515.     XClearArea(This->display, XtWindow(This->netscape_widget),
  516.            This->x + This->bannerWidth, 0,
  517.            This->width,
  518.            This->height, FALSE);
  519.  
  520.  
  521.     /* Compute the next location of the string. Also clear any space 
  522.        left to the top or bottom for vertical text*/
  523.     
  524.     if(This->direction == LEFT)
  525.     {
  526.     This->x -= 10;
  527.  
  528.     if(This->x + This->bannerWidth <= 0)
  529.         This->x = This->bannerWidth;
  530.     }
  531.     else if(This->direction == RIGHT)
  532.     {    
  533.     This->x += 10;
  534.  
  535.     if((int)This->x > (int)This->width)
  536.         This->x = -This->bannerWidth;
  537.     }
  538.     else if(This->direction == DOWN)
  539.     {
  540.     XClearArea(This->display, XtWindow(This->netscape_widget),
  541.            0, 0,
  542.            This->width,
  543.            This->y - This->ascent, FALSE);
  544.     
  545.     This->y += 2;
  546.  
  547.     if(This->y + This->bannerHeight > This->height)
  548.         This->y = 0;
  549.     }
  550.     else if(This->direction == UP)
  551.     {
  552.     XClearArea(This->display, XtWindow(This->netscape_widget),
  553.            0, This->y + This->descent,
  554.            0,
  555.            This->height, FALSE);
  556.  
  557.     This->y -= 2;
  558.  
  559.     if((int)This->y < - (int)This->bannerHeight)
  560.         This->y = This->height;
  561.     }
  562.  
  563.     /* Install a new timer for the next round */
  564.     
  565.     This->timerId = XtAppAddTimeOut(This->appContext, 100, DoAnimation, (XtPointer)instance); 
  566.  
  567. }
  568.  
  569. /*--- End custom code */
  570.  
  571.